package com.atguigu.daijia.dispatch.xxl.job;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.atguigu.daijia.common.constant.RedisConstant;
import com.atguigu.daijia.common.execption.GuiguException;
import com.atguigu.daijia.common.result.Result;
import com.atguigu.daijia.common.result.ResultCodeEnum;
import com.atguigu.daijia.dispatch.mapper.OrderJobMapper;
import com.atguigu.daijia.map.client.LocationFeignClient;
import com.atguigu.daijia.model.entity.dispatch.OrderJob;
import com.atguigu.daijia.model.form.map.SearchNearByDriverForm;
import com.atguigu.daijia.model.vo.dispatch.NewOrderTaskVo;
import com.atguigu.daijia.model.vo.map.NearByDriverVo;
import com.atguigu.daijia.model.vo.order.NewOrderDataVo;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j(topic = "xxl-job")
public class DispatcherJobHandler {
    @Resource
    private OrderJobMapper orderJobMapper;

    @Resource
    private LocationFeignClient locationFeignClient;

    @Resource
    private RedisTemplate redisTemplate;


    @XxlJob("firstJobHandler")
    public void dispatcherJobHandler() {
        System.out.println("测试");
    }


    @XxlJob("searchNearbyDrivers")
    public void searchNearbyDrivers() {

        // 1. 利用xxljob内置的工具类，获得当前 jobId
        long jobId = XxlJobHelper.getJobId();
        // 2. 根据jobid获得，去数据库获得job对象
        OrderJob orderJob = orderJobMapper.selectOne(new QueryWrapper<OrderJob>().eq("job_id", jobId));
        // 3. job对象的parameter属性，存储了newOrderTaskVo该类的信息
        String jsonStr = orderJob.getParameter();
        // 4. 获得newOrderTaskVo对象
        NewOrderTaskVo newOrderTaskVo = JSONObject.toJavaObject((JSON) JSONObject.parse(jsonStr), NewOrderTaskVo.class);
        Long orderId = newOrderTaskVo.getOrderId();
        // 5. 查询附近5公里的司机
        SearchNearByDriverForm searchNearByDriverForm = new SearchNearByDriverForm();
        searchNearByDriverForm.setLatitude(newOrderTaskVo.getStartPointLatitude());
        searchNearByDriverForm.setLongitude(newOrderTaskVo.getStartPointLongitude());
        searchNearByDriverForm.setMileageDistance(newOrderTaskVo.getExpectDistance());
        Result<List<NearByDriverVo>> result = locationFeignClient.searchNearByDriver(searchNearByDriverForm);
        System.out.println("获得的司机的信息" + result.getData());
        // 6. 将司机信息存入redis中。订单-附近司机列表
        if (result.getCode() != 200) {
            throw new GuiguException(ResultCodeEnum.DATA_ERROR);
        }
        List<NearByDriverVo> nearByDriverVoList = result.getData();
        if (CollectionUtils.isEmpty(nearByDriverVoList)) {
            return;
        }
        String redisKey = RedisConstant.DRIVER_ORDER_REPEAT_LIST + orderId;
        nearByDriverVoList.stream().forEach(nearByDriverVo -> {
            Long driverId = nearByDriverVo.getDriverId();
            // 防止重复添加
            if (redisTemplate.opsForSet().isMember(redisKey, newOrderTaskVo)) {
                return;
            }
            redisTemplate.opsForSet().add(redisKey, newOrderTaskVo);
            // 设置 16 分钟有效期，超过15分钟订单自动取消。
            redisTemplate.expire(redisKey, RedisConstant.DRIVER_ORDER_REPEAT_LIST_EXPIRES_TIME, TimeUnit.MINUTES);

            // 7. 将订单信息推送给范围内的每个司机 司机-订单列表
            NewOrderDataVo newOrderDataVo = new NewOrderDataVo();
            newOrderDataVo.setOrderId(newOrderTaskVo.getOrderId());
            newOrderDataVo.setStartLocation(newOrderTaskVo.getStartLocation());
            newOrderDataVo.setEndLocation(newOrderTaskVo.getEndLocation());
            newOrderDataVo.setExpectAmount(newOrderTaskVo.getExpectAmount());
            newOrderDataVo.setExpectDistance(newOrderTaskVo.getExpectDistance());
            newOrderDataVo.setExpectTime(newOrderTaskVo.getExpectTime());
            newOrderDataVo.setFavourFee(newOrderTaskVo.getFavourFee());
            newOrderDataVo.setDistance(nearByDriverVo.getDistance());
            newOrderDataVo.setCreateTime(newOrderTaskVo.getCreateTime());
            String redisKey1 = RedisConstant.DRIVER_ORDER_TEMP_LIST + driverId;
            redisTemplate.opsForList().leftPush(redisKey1, JSONObject.toJSONString(newOrderDataVo));
            // 过期时间：1分钟
            redisTemplate.expire(redisKey1, 2, TimeUnit.MINUTES);
        });

    }
}
